
# 从 qtpy 库导入 QtGui、QtWidgets 和 QtCore 模块
from qtpy import QtGui, QtWidgets, QtCore

class SelectionRect(QtWidgets.QGraphicsWidget):
    """
    SelectionRect 类用于创建一个选择矩形，继承自 QtWidgets.QGraphicsWidget。
    该矩形用于在图形场景中进行选择操作，根据不同的修饰键显示不同的背景颜色。
    """
    # 定义选择矩形的默认背景颜色
    __backgroundColor = QtGui.QColor(100, 100, 100, 50)
    # 定义添加选择时的背景颜色
    __backgroundAddColor = QtGui.QColor(0, 100, 0, 50)
    # 定义减去选择时的背景颜色
    __backgroundSubColor = QtGui.QColor(100, 0, 0, 50)
    # 定义切换选择时的背景颜色
    __backgroundSwitchColor = QtGui.QColor(0, 0, 100, 50)
    # 定义选择矩形的边框画笔，这里存在类 'Qt' 的未解析的特性引用 'DashLine' 问题
    __pen = QtGui.QPen(QtGui.QColor(255, 255, 255), 1.0, QtCore.Qt.DashLine)

    def __init__(self, graph, mouseDownPos, modifiers):
        """
        初始化选择矩形。

        :param graph: 包含选择矩形的图形场景所在的图对象
        :param mouseDownPos: 鼠标按下的位置
        :param modifiers: 键盘修饰键状态
        """
        super(SelectionRect, self).__init__()
        # 设置选择矩形的 Z 值，确保其显示在其他元素之上
        self.setZValue(2)

        self.__graph = graph
        # 将选择矩形添加到图形场景中
        self.__graph.scene().addItem(self)
        self.__mouseDownPos = mouseDownPos
        self.__modifiers = modifiers
        # 设置选择矩形的位置为鼠标按下的位置
        self.setPos(self.__mouseDownPos)
        # 初始化选择矩形的大小为 0
        self.resize(0, 0)
        # 标记是否选择完全相交的项目
        self.selectFullyIntersectedItems = False

    def collidesWithItem(self, item):
        """
        判断选择矩形是否与指定项目相交。
        此方法存在与基类 'QGraphicsItem' 中方法签名不匹配的问题。

        :param item: 要检查的图形项目
        :return: 如果相交则返回 True，否则返回 False
        """
        if self.selectFullyIntersectedItems:
            # 若选择完全相交的项目，则检查选择矩形的场景边界是否包含项目的场景边界
            return self.sceneBoundingRect().contains(item.sceneBoundingRect())
        # 调用父类的 collidesWithItem 方法进行判断
        return super(SelectionRect, self).collidesWithItem(item)

    def setDragPoint(self, dragPoint, modifiers):
        """
        根据鼠标拖动点和修饰键更新选择矩形的位置和大小。

        :param dragPoint: 鼠标拖动的位置
        :param modifiers: 键盘修饰键状态
        """
        self.__modifiers = modifiers
        # 初始化选择矩形的左上角位置为鼠标按下的位置
        topLeft = QtCore.QPointF(self.__mouseDownPos)
        # 初始化选择矩形的右下角位置为鼠标拖动的位置
        bottomRight = QtCore.QPointF(dragPoint)
        if dragPoint.x() < self.__mouseDownPos.x():
            # 若鼠标拖动点在鼠标按下点的左侧，更新左上角和右下角的 x 坐标
            topLeft.setX(dragPoint.x())
            bottomRight.setX(self.__mouseDownPos.x())
        if dragPoint.y() < self.__mouseDownPos.y():
            # 若鼠标拖动点在鼠标按下点的上方，更新左上角和右下角的 y 坐标
            topLeft.setY(dragPoint.y())
            bottomRight.setY(self.__mouseDownPos.y())
        # 设置选择矩形的位置为左上角位置
        self.setPos(topLeft)
        # 根据左上角和右下角的坐标更新选择矩形的大小
        self.resize(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())

    def paint(self, painter, option, widget):
        """
        绘制选择矩形。
        此方法存在与基类 'QGraphicsWidget' 中方法签名不匹配的问题。

        :param painter: 用于绘制的 QPainter 对象
        :param option: 绘制选项
        :param widget: 可选的绘制部件
        """
        # 获取选择矩形的窗口框架矩形
        rect = self.windowFrameRect()
        if self.__modifiers == QtCore.Qt.NoModifier:
            # 若没有按下修饰键，设置画笔的画刷为默认背景颜色
            painter.setBrush(self.__backgroundColor)
        if self.__modifiers == QtCore.Qt.ShiftModifier:
            # 若按下 Shift 键，设置画笔的画刷为添加选择的背景颜色
            painter.setBrush(self.__backgroundAddColor)
        elif self.__modifiers == QtCore.Qt.ControlModifier:
            # 若按下 Ctrl 键，设置画笔的画刷为切换选择的背景颜色
            painter.setBrush(self.__backgroundSwitchColor)
        elif self.__modifiers == QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier:
            # 若同时按下 Ctrl 和 Shift 键，设置画笔的画刷为减去选择的背景颜色
            painter.setBrush(self.__backgroundSubColor)
        # 设置画笔的边框
        painter.setPen(self.__pen)
        # 绘制矩形
        painter.drawRect(rect)

    def destroy(self):
        """
        从图形场景中移除选择矩形。
        """
        self.__graph.scene().removeItem(self)